home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / PortScanner / portscanner.c < prev    next >
C/C++ Source or Header  |  2000-05-25  |  11KB  |  322 lines

  1. /***********************************************************/
  2. /* PORTSCANNER.C by Tennessee Carmel-Veilleux              */
  3. /* Contact info: (I speak french and english :)            */
  4. /* e-mail: veilleux@ameth.org                              */
  5. /* www: http://www.ameth.org/~veilleux                */
  6. /*                                                         */
  7. /* Version 1.2                                             */
  8. /* The author of this program offers no waranty at all     */
  9. /* about the correct execution of this software material.  */
  10. /* Furthermore, the author can NOT be held responsible for */
  11. /* any physical or moral damage caused by the use of this  */
  12. /* software.                                               */
  13. /*                                                         */
  14. /* -> This program will scan for TCP ports listening on a  */
  15. /*    remote or local host inside the range you give to it.*/
  16. /*    I offer no warranty over the accuracy though :)      */
  17. /*    There are 3 verbose modes: No info, service info, and*/
  18. /*    full info. No info is good of you only want the list */
  19. /*    of the ports, no more info. The best mode is Full    */
  20. /*    info, as you get error information,etc. The main     */
  21. /*    output is STDOUT, and ALL the errors go to STDERR.   */
  22. /*                                                         */
  23. /*    History: v1.0 : August 9 1998 -> First release       */
  24. /*             v1.2 : August 19 1998 -> Major release      */
  25. /***********************************************************/
  26.  
  27. #include <stdio.h>
  28. #include <sys/socket.h>
  29. #include <sys/types.h>
  30. #include <netinet/in.h>
  31. #include <unistd.h>
  32. #include <netdb.h>
  33. #include <sys/time.h>
  34. #include <fcntl.h>
  35. #include <arpa/inet.h>
  36. #include <string.h>
  37. #include <stdlib.h>
  38. #include <errno.h>
  39.  
  40. #define VERSION "1.2"
  41.  
  42. int sock = -1; /* Main socket */
  43. struct sockaddr_in address, address2; /* Address structure */
  44. struct sockaddr *sub_address; /* Address in subnet */
  45. int result; /* Temporary results for operations */
  46. u_short current_port = 0; /* Current port being scanned */
  47. u_short base_port = 1; /* Base port to start scanning from */
  48. u_short end_port = 1024; /* Port number to end scanning at */
  49. u_char start_address = 1; /* Subnet address to start at */
  50. u_char end_address = 254; /* Subnet address to finish at */
  51. int verbose = 0; /* Level of verbosity */
  52. struct hostent *host_info; /* Host information structure */
  53. struct servent *service_info; /* Service information structure */
  54. char addr[1024]; /* Address to connect to, 1024 chars max */
  55. int strobe = 0; /* 1 if we want strobe scanning */
  56. int subnet = 0; /* 1 if we want subnet scanning */
  57. int i; /* Counter variable */
  58.         
  59. void port_scan(void);
  60. void print_usage(int finish);
  61. void print_help(int finish);
  62. void print_info(int finish);
  63.         
  64. void print_usage(int finish) {
  65.     fprintf(stderr,
  66. "Usage: portscan [-b start] [-e end] [-bm start] [-em end] [-v[v]] [-a] [-s] [-i] [-? | h] <address>\n");
  67.     if (finish) 
  68.      exit(1);
  69. }
  70.  
  71. void print_help(int finish) {
  72.  print_usage(0);
  73.  fprintf(stderr,"\n-b start: Specify the port at which we begin scanning\n");
  74.  fprintf(stderr,"-e end: Specify the port at which we stop scanning\n");
  75.  fprintf(stderr,"-bm: Subnet machine number at which to start scanning [dfl=1]\n");
  76.  fprintf(stderr,"-em: Subnet machine number at which to stop scanning [dfl=254]\n");  
  77.  fprintf(stderr,"-v: Level 1 of verbosity, basic information\n");
  78.  fprintf(stderr,"-vv: Level 2 of verbosity, full information report\n");
  79.  fprintf(stderr,"-a: if we want subnet scanning (start at .1, end at .254)\n");
  80.  fprintf(stderr,"-s: strobe scanning: scan only ports found in /etc/services, much faster\n");
  81.  fprintf(stderr,"-? or -h: print this help text\n");
  82.  fprintf(stderr,"-i: Copyright and version information\n");
  83.  if (finish) exit(1);
  84.  
  85. void print_info(int finish) {       
  86.  fprintf(stderr,"portscanner v%s was written by Tennessee Carmel-Veilleux\n",VERSION);
  87.  fprintf(stderr,"This version compiled on %s at %sEST\n",__DATE__,__TIME__);
  88.  fprintf(stderr,"This program is licensed under the GPL. See www.gnu.org for more info on the license\n");
  89.  if (finish) exit(1);
  90. }
  91.        
  92. int main(int argc, char **argv)
  93.    if (argc < 2) {
  94.     print_usage(1);
  95.    }
  96.    
  97.    switch (argc) {
  98.      case 2: if (!strcmp(argv[1],"-i")) {
  99.               print_info(1);
  100.              } else if ((!strcmp(argv[1],"-?")) || (!strcmp(argv[1],"-h"))) {
  101.               print_help(1);
  102.              } else { 
  103.         break;
  104.          }    
  105.         
  106.      default: for (i = 1; i < argc - 1; i++) {
  107.        if (!strcmp(argv[i],"-v")) { 
  108.         verbose = 1;
  109.        } else 
  110.        if (!strcmp(argv[i],"-vv")) {
  111.         verbose = 2;
  112.        } else
  113.        if (!strcmp(argv[i],"-i")) {
  114.         print_info(0);
  115.        } else
  116.        if ((!strcmp(argv[i],"-h")) || (!strcmp(argv[1],"-?"))) {
  117.         print_help(0);
  118.        } else
  119.        if (!strcmp(argv[i],"-a")) {
  120.         subnet = 1;
  121.        } else
  122.        if (!strcmp(argv[i],"-s")) {
  123.         strobe = 1;
  124.        } else
  125.        if (!strcmp(argv[i],"-b")) {
  126.         if ((i+1) > (argc - 1)) { 
  127.          print_usage(1);
  128.         } else {
  129.            base_port = (u_short)atoi(argv[i+1]);
  130.            i++;
  131.         }
  132.        } else 
  133.        if (!strcmp(argv[i],"-e")) {
  134.         if ((i+1) > (argc - 1)) {
  135.          print_usage(1);
  136.         } else {
  137.            end_port = (u_short)atoi(argv[i+1]);
  138.            i++;
  139.         }
  140.        } else
  141.       if (!strcmp(argv[i],"-bm")) {
  142.        if ((i+1) > (argc - 1)) {
  143.      print_usage(1);
  144.        } else {
  145.       start_address = (u_char)atoi(argv[i+1]);
  146.       i++;
  147.        }
  148.       } else 
  149.       if (!strcmp(argv[i],"-em")) {
  150.         if ((i+1) > (argc - 1)) {
  151.          print_usage(1);
  152.         } else {
  153.            end_address = (u_char)atoi(argv[i+1]);
  154.            i++;
  155.         }
  156.        }
  157.      }
  158.     }     
  159.     
  160.    if ((base_port > end_port) || ((short)base_port < 0)) { 
  161.      fprintf(stderr,"Bad port range : start=%d end=%d !\n", base_port, end_port);
  162.      exit(1);
  163.    }
  164.    
  165.    if ((start_address > end_address)) { 
  166.      fprintf(stderr,"Bad address range : start=%d end=%d !\n", start_address, end_address);
  167.      exit(1);
  168.    }
  169.    
  170.    if (subnet) printf("Subnet scanning enabled\n");
  171.     
  172.     bzero((char *)&address, sizeof(address));
  173.     address.sin_family = AF_INET;
  174.     
  175.       
  176.     strncpy(addr,argv[argc - 1],1023);
  177.     addr[1023] = 0;
  178.       
  179.     if (verbose == 2) printf("Resolving: %s ->",addr);
  180.     if ((host_info = gethostbyname(addr)))
  181.     {
  182.       bcopy(host_info->h_addr, (char *)&address.sin_addr,host_info->h_length);
  183.       if (verbose == 2) printf(" resolved\n");
  184.     } 
  185.    else if ((address.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE)
  186.    {
  187.             fprintf(stderr,"Could not get %s host entry !\n",argv[1]);
  188.             printf(" NOT resolved !!!\n");
  189.             exit(1);
  190.    }
  191.    else if (verbose == 2) printf(" address valid\n");
  192.    
  193.   if (subnet) { 
  194.    if (verbose == 2) printf("Starting SUBNET port scanning\n");
  195.    for (i=start_address; i <= end_address; i++) {
  196.       sub_address = (struct sockaddr *)&address;
  197.       sub_address->sa_data[5] = i;
  198.       
  199.       if (verbose == 2) printf("Current address: ");
  200.       
  201.       printf("%d.%d.%d.%d\n",(u_char)sub_address->sa_data[2],(u_char)sub_address->sa_data[3],
  202.                          (u_char)sub_address->sa_data[4],(u_char)sub_address->sa_data[5]);
  203.       
  204.       bcopy(sub_address,&address2,sizeof(address2));    
  205.    
  206.       if (verbose == 2) {
  207.             printf("Port range: %d to %d\n",base_port,end_port);
  208.       }
  209.       port_scan();
  210.       printf("#\n");
  211.    }
  212.    if (verbose == 2) printf("SUBNET scanning completed\n");
  213.   } else {
  214.       sub_address = (struct sockaddr *)&address;
  215.       
  216.       if (verbose == 2) printf("Current address: ");
  217.       
  218.       printf("%d.%d.%d.%d\n",(u_char)sub_address->sa_data[2],(u_char)sub_address->sa_data[3],
  219.                          (u_char)sub_address->sa_data[4],(u_char)sub_address->sa_data[5]);
  220.       
  221.       bcopy(sub_address,&address2,sizeof(address2));    
  222.    
  223.       if (verbose == 2) {
  224.             printf("Port range: %d to %d\n",base_port,end_port);
  225.       }
  226.       port_scan();
  227.       printf("#\n");
  228.   }
  229.    exit(0);
  230. }
  231.  
  232. void port_scan(void) {
  233.    int finished = 0; /* Set to 1 when strobe scanning is finished */
  234.    int goodproto = 0; /* set to 1 if protocol returned in service info structure can be scanned */
  235.    
  236.    if ((strobe) && (verbose == 2)) { 
  237.        printf("Strobe scanning started...\n");
  238.        setservent(1);
  239.    }
  240.    
  241.    while (((base_port + current_port) <= end_port) || !finished) {
  242. /*  fprintf(stderr,"Trying port: %d\n",base_port+current_port); */
  243.     sock = socket(PF_INET, SOCK_STREAM, 0);
  244.     if (sock == -1)
  245.      {
  246.     // fprintf(stderr, "Error assigning master socket: %s\n",sys_errlist[errno]);
  247.     fprintf(stderr, "Error assigning master socket: sys_errlist[errno]\n");
  248.     exit(-1);
  249.      } 
  250.    
  251.     if (strobe) {
  252.      while(!goodproto) {
  253.       service_info = getservent();
  254.       if (!service_info) break;
  255.       if (!strcmp(service_info->s_proto,"tcp") && (ntohs(service_info->s_port) <= end_port) && (ntohs(service_info->s_port) >= base_port)) {
  256.        goodproto = 1;
  257.        break;
  258.       }
  259.      }
  260.      if (!goodproto) break;
  261.        
  262.      if (!service_info) {
  263.        finished = 1;
  264.        break;
  265.      }
  266.      if (goodproto) address2.sin_port = service_info->s_port;
  267.      goodproto = 0;
  268.     } else address2.sin_port = htons(base_port+current_port);
  269.  
  270.     if (!finished)
  271.     if (connect(sock, (struct sockaddr *)&address2, sizeof(address2)) == 0) {
  272.      switch (verbose) {
  273.       case 0: if (strobe)
  274.            printf("%d\n",ntohs(service_info->s_port));
  275.               else
  276.            printf("%d\n",base_port+current_port);
  277.               break;
  278.       case 1: if (!strobe) {
  279.            service_info = getservbyport(htons(base_port+current_port),"tcp");
  280.                if (!service_info) {
  281.                 printf("%d -> service name unknown\n",base_port+current_port);
  282.                } else {
  283.                 printf("%d -> %s\n",base_port+current_port,service_info->s_name);
  284.                }
  285.               } else printf("%d -> %s\n",ntohs(service_info->s_port),service_info->s_name);
  286.               break; 
  287.       case 2: if (!strobe) {
  288.            service_info = getservbyport(htons(base_port+current_port),"tcp");
  289.                if (!service_info) {
  290.                 printf("Port %d found. Service name unknown\n",base_port+current_port);
  291.                } else {
  292.                 printf("Port %d found. Service name: %s\n",base_port+current_port,service_info->s_name);
  293.                }
  294.               }  else {
  295.         printf("Port %d found. Service name: %s\n",ntohs(service_info->s_port),service_info->s_name);
  296.               }
  297.               break; 
  298.      } 
  299.     }  else if (errno == 113) {
  300.          fprintf(stderr,"No route to host !\n");
  301.          if (!subnet) {
  302.       close(sock);
  303.       exit(1);
  304.      }
  305.        } 
  306. /*     fprintf(stderr,"Error %d connecting socket %d to port %d: %s\n",
  307.      errno,sock,base_port+current_port,sys_errlist[errno]); */ 
  308.      close(sock);
  309.      current_port++;
  310.      if (base_port+current_port >= end_port) {
  311.        finished = 1;
  312.      }
  313.     /* fprintf(stderr,"current_port: %d,b: %d,e:%d,b+c:%d\n", current_port, base_port,end_port,base_port+current_port); */
  314.    }
  315.  
  316.   if (verbose == 2) printf("Port scan finished !\n");
  317.   if (strobe) endservent();
  318. }
  319.  
  320.